package cn.hushi.test;

import cn.hushi.one2many.Order;
import cn.hushi.utils.HibernateUtil;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import java.util.List;

public class Demo1 {
    /**
     * 演示HQL的查询（单表查询）
     *    1）全表查询
     *    2）别名查询
     *    3）条件查询
     *    4）具名查询
     *    5）分页查询
     *    6）查询排序
     *    7）聚合查询
     *    8）投影查询
     *
     */

    /**
     * 1）全表查询
     */
    @Test
    public void test1() {
        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();

        Query query = session.createQuery("from Order");
        List<Order> list = query.list();
        for (Order order : list) {
            System.out.println(order);
        }

        tx.commit();
        session.close();

    }

    /**
     * 2）别名查询
     */
    @Test
    public void test2() {
        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();

        Query query = session.createQuery("from Order o");
        List<Order> list = query.list();
        for (Order order : list) {
            System.out.println(order);
        }
        tx.commit();
        session.close();
    }

    /**
     * 3）条件查询
     */
    @Test
    public void test3() {
        // 1. 获取Hibernate Session实例，用于执行数据库操作
        Session session = HibernateUtil.getSession();

        // 2. 开启一个新的数据库事务
        Transaction tx = session.beginTransaction();

        // ** 方法一：使用HQL（Hibernate Query Language）直接在查询语句中指定查询条件值 **
        // 3. 创建一个HQL查询语句，查询orderno为'1001'的Order记录
        Query query = session.createQuery("from Order where orderno = '1001'");

        // 4. 执行查询并获取结果集，存储为Order对象列表
        List<Order> list = query.list();

        // 5. 遍历结果集，打印每个Order对象的详细信息
        for (Order order : list) {
            System.out.println(order);
        }

        // ** 方法二：使用HQL并结合setParameter方法动态设置查询条件值 **
        // 6. 创建一个带占位符的HQL查询语句，查询orderno为指定值的Order记录
        Query query1 = session.createQuery("from Order where orderno = ?");

        // 7. 使用setParameter方法为查询语句中的第一个参数设置实际值（此处为'1001'）
        query1.setParameter(0, "1001");

        // 8. 执行查询并获取结果集，存储为Order对象列表
        List<Order> list1 = query1.list();

        // 9. 遍历结果集，打印每个Order对象的详细信息
        for (Order order : list1) {
            System.out.println(order);
        }

        // 10. 提交当前事务，使上述数据库操作生效
        tx.commit();

        // 11. 关闭当前Session，释放资源
        session.close();
    }

    /**
     * 4）具名查询
     */
    @Test
    public void test4() {
        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();

        // 创建一个HQL查询语句，使用具名参数":orderno"表示待指定的订单号
        Query query = session.createQuery("from Order where orderno = :orderno");
        // 使用setParameter方法为具名参数":orderno"设置实际值（此处为'1001'）
        query.setParameter("orderno", "1001");
        List<Order> list = query.list();
        for (Order order : list) {
            System.out.println(order);
        }
        tx.commit();
        session.close();
    }

    /**
     * 5）分页查询
     */
    @Test
    public void test5() {
        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();

        Query query = session.createQuery("from Order");
        //设置起始行，从0开始
        query.setFirstResult(2);
        //设置查询行数
        query.setMaxResults(2);

        List<Order> list = query.list();
        for (Order order : list) {
            System.out.println(order);
        }
        tx.commit();
        session.close();
    }

    /**
     * 6）查询排序
     */
    @Test
    public void test6() {
        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();
        // 创建一个HQL查询语句，用于从Order表中选取所有记录，并按id字段降序排序
        Query query = session.createQuery("from Order order by id desc");
        List<Order> list = query.list();
        for (Order order : list) {
            System.out.println(order);
        }
        tx.commit();
        session.close();
    }

    /**
     * 7）聚合查询
     */
    @Test
    public void test7() {
        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();

        // ** 方法一：通过查询语句获取Order表中的总记录数，并将其作为List<Long>返回 **
        Query query = session.createQuery("select count(*) from Order");
        // 执行查询，得到一个包含单个元素（即总记录数）的List<Long>
        List<Long> list = query.list();
        // 从List中获取并打印第一个（也是唯一一个）元素，即Order表的总记录数
        Long count = list.get(0);
        System.out.println(count);

        // ** 方法二：通过查询语句获取Order表中的总记录数，并将其作为单个Long值返回 **
        Query query1 = session.createQuery("select count(*) from Order");
        // 执行查询，直接获取并打印Order表的总记录数（uniqueResult方法确保返回单个结果）
        Long l = (Long) query1.uniqueResult();
        System.out.println(l);

        tx.commit();
        session.close();
    }

    /**
     * 8）投影查询
     */
    @Test
    public void test8() {
        Session session = HibernateUtil.getSession();
        Transaction tx = session.beginTransaction();

//        //方法一
        Query query = session.createQuery("select orderno,product_name from Order");
        List<Object[]> list = query.list();
        for (Object[] objects : list) {
            for (Object object : objects) {
                System.out.print(object+"\t");
            }
            System.out.println();
        }

        //方法二
        /**
         * 这里要先在Order类里面生成有参和无参构造方法，不然会报错
         * 这里要把toString修改为
         * ----
              public String toString() {
                  return "Order{" +
                          "id=" + id +
                          ", orderno='" + orderno + '\'' +
                          ", product_name='" + product_name + '\'' +
                         ", cust_id=" + customer()+
                        '}';
              }
         *----
         * 不修改会报空指针异常，可能是因为对象里面还有嵌套对象的原因
         * 半解决，修改了toString后cust_id=null和想要的结果不一致
         */
//        Query query1 = session.createQuery("select new cn.hushi.one2many.Order(orderno,product_name) from Order");
//        List<Order> list1 = query1.list();
//        System.out.println(query1);
//        for (Order order : list1) {
//            System.out.println(order);
//        }
//        tx.commit();
//        session.close();
    }
}